import 'reflect-metadata'; // 导入reflect-metadata模块: 支持反射
import { InversifyExpressServer } from 'inversify-express-utils';
import { Container } from 'inversify'; // 引入容器
import express from 'express';
import { PrismaClient } from '@prisma/client';
import { User } from './src/user/controller';
import { UserService } from './src/user/service';
import { PrismaDB } from './src/db';
import { JWT } from './src/jwt';

// 创建容器
const container = new Container();

/**
 * 将各模块注入容器
 * 在Inversify中， container.bind 方法用于将特定的服务标识符（service identifier）绑定到一个特定的实现。
 * 这是依赖注入的关键步骤之一，它允许你告诉容器当需要某个特定服务时应该提供哪个实现。
 * bind后面绑定的标识符应该和@inject注入的标识符一致, 比如bind('a'), @inject('a')
 */
container.bind(User).to(User);
container.bind(UserService).to(UserService);

// 将PrismaClient注入容器, 避免重复创建实例
// 注入工厂
container.bind<PrismaClient>('PrismaClient').toFactory(() => {
  return () => {
    return new PrismaClient()
  }
})
// 将PrismaClient实例注入容器, 避免重复创建实例
container.bind(PrismaDB).to(PrismaDB);

// 绑定JWT服务到容器中
container.bind(JWT).to(JWT);

// 创建一个InversifyExpressServer实例，并传入容器
const server = new InversifyExpressServer(container);

// 设置中间件统一放到这里
server.setConfig((app) => {
  // 解析body请求体
  app.use(express.json());
  // 集成passport
  app.use(container.get(JWT).init());
})

// Create a new server instance
const app = server.build();


app.listen(3000, () => {
  console.log('Server running on port 3000');
});


declare global {
  namespace Express {
    interface User {
      id: string;
      name: string;
      email: string;
    }
  }
}


